<script>
  //  1 、字符串隐藏部分内容
  // 说明
  // 实现一个方法，接收一个字符串和一个符号，将字符串中间四位按指定符号隐藏
  //    1. 符号无指定时使用星号（*）
  //    2. 接收的字符串小于或等于四位时，返回同样长度的符号串，等同于全隐藏，如 123，隐藏后是**
  //    3. 字符串长度是大于四位的奇数时，如 123456789，隐藏后是 12****789，奇数多出来的一位在末尾
  // 示例：
  mask('alibaba', '#');  // a####ba
  mask('85022088');   // 85****88
  mask('hello');  //****o
  mask('abc', '?');  // ???
  mask('阿里巴巴集团', '?'); // 阿????团

  function mask(str, sym = '*', num = 4) {
    const len = str.length
    let result = ''
    if (len < num) {
      for (let i = 0; i < len; i++) {
        result += sym
      }
    } else {
      const min = Math.floor((len - num) / 2)//向下取整
      const strArr = str.split('')
      for (let i = 0; i < num; i++) {
        strArr[min + i] = sym
      }
      strArr.forEach(item => {
        result += item
      })
    }
    console.log(result);
  }

  // 2、实现go函数，使得函数执行能输出如下结果规则
  _go(['a', 'b', 'c', 'd'], 2);
  // => [['a', 'b'], ['c', 'd']]

  _go(['a', 'b', 'c', 'd'], 3);
  // => [['a', 'b', 'c'], ['d']]

  _go(['a', 'b', 'c', 'd'], 5);
  // => [['a', 'b', 'c', 'd']]

  _go(['a', 'b', 'c', 'd'], 0);
  // => []

  function _go(arr, num = 2) {
    if (!Number.isInteger(num) || num <= 0) return console.log('输入正整数分割数组')
    if (!Array.isArray(arr) || !arr.length) return console.log('输入非空数组')

    const result = []
    // const len = Math.ceil(arr.length / num)

    // for (let i = 0; i < len; i++) {
    //   result[i] = []
    //   for (let j = 0; j < num; j++) {
    //     result[i].push(arr[i * num + j])
    //   }
    // }
    for (let i = 0; i < arr.length; i++) {
      i % num === 0 && (result[i / num] = [])
      result[Math.floor(i / num)].push(arr[i])
    }

    // result[len - 1] = result[len - 1].filter(i => i)
    console.log(result);
  }

  // 3、将以下的输入inputArr 转化成 output的形式，数组转为树。
  let inputArr = [
    {
      id: 2, val: '班级1', parentId: 1,
    },
    {
      id: 4, val: '班级3', parentId: 1,
    },
    {
      id: 5, val: '学生1', parentId: 2,
    },
    {
      id: 1, val: '学校'
    },
    {
      id: 6, val: '学生2', parentId: 3,
    },
    {
      id: 3, val: '班级2', parentId: 1,
    },
    {
      id: 7, val: '学生3', parentId: 4,
    }
  ]

  // let output = {
  //   id: 1,
  //   val: '学校',
  //   children: [{
  //     id: 2,
  //     val: '班级1',
  //     children: [
  //       {
  //         id: 5,
  //         val: '学生1'
  //       }
  //     ]
  //   }, {
  //     id: 3,
  //     val: '班级2',
  //     children: [
  //       {
  //         id: 6,
  //         val: '学生2'
  //       }
  //     ]
  //   }, {
  //     id: 4,
  //     val: '班级3',
  //     children: [
  //       {
  //         id: 7,
  //         val: '学生3'
  //       }
  //     ]
  //   }]
  // }
  function splitArr(arr) {
    let result = []
    arr.forEach(i => {
      if (!i.parentId) result.push(i) //先添加初始值 没有parentId
    })

    const parentIdArr = [...new Set(arr.map(i => i.parentId))] //提取parentId,去重

    function inside(filterArr, pid) {
      const _result = filterArr.filter(item => item.parentId === pid).map(i => {
        delete i.parentId
        return i
      }) //过滤出来一个数组,这就是需要的数据,但是还需要挂载子数组

      const newArr = filterArr.filter(function (obj1, index) { //过滤掉已经使用的数组,剩下还没有分配的数组
        return !_result.find(function (obj2) {
          return obj1.id === obj2.id
        })
      })
      const _parentIdArr = [...new Set(newArr.map(i => i.parentId))]

      _parentIdArr.length && _result.forEach(item => { //剩下的数组还有内容就继续执行
        if (_parentIdArr.some(i => i === item.id)) { //如果有检测到父id就执行一次回调函数
          item.children = inside(newArr, item.id)
        }
      })
      return _result
    }

    result.forEach(item => {
      if (parentIdArr.some(i => i === item.id)) { //如果有,就调用这个方法
        item.children = inside(arr.filter(i => i.parentId), item.id)
      }
    })

    return result.length === 1 ? result[0] : result
  }
  console.log(splitArr(inputArr));
</script>

<script>
  const task = (light, timer) => {
    return new Promise((resolve, reject) => {
      const actions = {
        'red': () => console.log('red'),
        'green': () => console.log('green'),
        'yellow': () => console.log('yellow'),
        'default': () => console.log(`not have ${light} light`)
      }
      setTimeout(() => {
        actions[light] ? actions[light]() : actions['default']()
        resolve()
      }, timer)
    })
  }

  const step = async () => {
    await task('red', 3000)
    await task('green', 2000)
    await task('yellow', 1000)
    await task('test', 500)
    step()
  }

// step()
</script>
<script>
  //手写call, apply, bind
  //   都是改变this指向的；

  // 第一个参数都是this要指向的对象；

  // 都可以利用后续参数传参；
  // call和bind的参数是依次传参，一一对应的；

  // 但apply只有两个参数，第二个参数为数组；

  // call和apply都是对函数进行直接调用，而bind方法返回的仍是一个函数；

  const obj = { name: '222' }
  console.dir(name);
  function name(...args) {
    console.log(this, args);
  }
  Function.prototype.myApply = function (thisArgs, argArray) {
    // 1.获取到要执行的函数
    var fn = this;
    // 2.处理绑定的 thisArgs
    thisArgs = (thisArgs !== null && thisArgs !== undefined) ? Object(thisArgs) : window;
    // 3.执行函数
    thisArgs.fn = fn;

    argArray = argArray || [];

    var result = thisArgs.fn(...argArray);
    delete thisArgs.fn;
    return result;

  };
  name.myApply(obj, ['2'])
  console.log('1111', Math.max({}));
  const s1 = new Set([null, null, null, 1, 2, 3])
  console.log('11111', s1);

  Function.prototype.myBind = function (obj, ...args) {
    const _this = this
    obj.fn = _this
    const result = obj.fn(args)
    delete obj.fn
    return () => {
      result
    }
  }
  function fun() {
    console.log('打印', this.xxxa);
  }
  const text = { xxxa: 'bind' }
  fun.myBind(text)()
</script>
<script>
  var x = 1;
  function test() {
    // console.log(x); // Uncaught ReferenceError: x is not defined
    let x = 2;
  }
  test()
</script>
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>

  <a id="aas">1111111</a>


  <div style="height: 2000px;background-color: red;"></div>








  <p id="adas">22222222222</p>
  <div style="height: 2000px;background-color: red;"></div>
  <script>
    aas.addEventListener('click', () => {
      document.querySelector('#adas').scrollIntoView()
    })
    console.log(isNaN(Number('2.3.3')));
  </script>
</body>

</html>